"""
逻辑回归=对数几率回归
优点
1. 对线性关系的拟合效果非常好
特征和标签之间的线性关系极强的数据，比如信用卡欺诈、评分卡制作，电商中营销预测等相关的数据，都是逻辑回归的强项。
对于非线性数据的预测效果非常差
金融/银行应用效果好
2. 计算快
3. 分类结果不是固定的0，1，而是小数形式呈现的类概率数字
4. 抗噪能力强


本质：是一个返回对数几率的，在线性数据上表现优异的分类器。它主要被应用在金融领域。
其数学目的是求解能够让模型最优化的参数θ的值，并基于参数θ和特征矩阵计算出逻辑回归的结果。

损失函数
衡量参数θ的优劣的评估指标，用来求解最优参数的工具
损失函数小，模型在训练集上表现优异，拟合充分，参数优秀
损失函数大，模型在训练集上表现差劲，拟合不足，参数糟糕
追求让损失函数最小化的参数组合

对逻辑回归中过拟合的控制，通过正则化来实现
正则化是用来防止模型过拟合的过程，常用的有L1正则化和L2正则化两种选项，分别通过在损失函数的后面加上L1范式和L2范式的倍数来实现。这个增加的范式，被称为“正则项”，也被称为“惩罚项”。
通过加上范式的方法来改变损失函数来改变参数取值，以此来改变模型。

"""
from sklearn.linear_model import LogisticRegression as LR
from sklearn.datasets import load_breast_cancer
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

"""
# 参数
# penalty   指定正则化方式。可输入L1或L2，默认L2。如果选择L1，参数solver只能使用liblinear，若使用L2，参数solver中所有秋节方式都可以使用。
# L1正则化会将参数压缩为0，L2正则化指挥让参数尽量小，不会取到0。
# 在L1正则化逐渐加强的过程中，携带信息量小的对模型贡献小的特征的参数，会比携带信息量大的对模型贡献大的特征的参数更快地变成0，所以L1正则化本质上是一个特征选择地过程，它掌握了参数矩阵地稀疏性。在数据量很大，数据维度很高地情况，倾向于使用L1正则化。如果目的只是为了防止过拟合，选择L2正则化就足够了。

# C         正则化强度的倒数，必须是大于0的浮点数，默认1.0。C越小，对损失函数的惩罚越重，正则化效果越强，参数θ被压缩得越小。

"""

data=load_breast_cancer()
x=data.data
y=data.target

print(x.shape)
print(set(y))

# lrl1=LR(penalty='l1',solver='liblinear',C=0.05,max_iter=1000)
# lrl2=LR(penalty='l2',solver='liblinear',C=0.5,max_iter=1000)
# lrl3=LR(penalty='l1',solver='liblinear',C=0.5,max_iter=1000)
#
# lrl1=lrl1.fit(x,y)
# lrl2=lrl2.fit(x,y)
# lrl3=lrl3.fit(x,y)
#
# print((lrl1.coef_!=0).sum(axis=1))
# print((lrl2.coef_!=0).sum(axis=1))
# print((lrl3.coef_!=0).sum(axis=1))

"""
对比lrl1,l2：L1有些特征的系数会变为0，L2会保留所有特征的系数。
对比lrl1,l3：C越小，l1特征系数不为0的特征数量越少。即保留了更少的特征。
"""

x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=50)
r1=[]
r2=[]
r3=[]
r4=[]

for i in np.linspace(0.05,1,19):
    lrl1 = LR(penalty='l1',solver='liblinear',C=i,max_iter=1000)
    lrl1=lrl1.fit(x_train,y_train)
    r1.append(accuracy_score(lrl1.predict(x_test),y_test))
    r2.append(accuracy_score(lrl1.predict(x_train), y_train))

    lrl2 = LR(penalty='l2',solver='liblinear',C=i,max_iter=1000)
    lrl2=lrl2.fit(x_train,y_train)
    r3.append(accuracy_score(lrl2.predict(x_test),y_test))
    r4.append(accuracy_score(lrl2.predict(x_train), y_train))

plt.figure()
plt.plot(np.linspace(0.05,1,19),r1,alpha =0.5,color='red',label="l1_test")
plt.plot(np.linspace(0.05,1,19),r2,color='red',label="l1_train")
plt.plot(np.linspace(0.05,1,19),r3,alpha =0.5,color='black',label="l2_test")
plt.plot(np.linspace(0.05,1,19),r4,color='black',label="l2_train")
plt.legend()
plt.show()